package core.rdd.持久化;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.storage.StorageLevel;
import scala.Tuple2;

import java.util.Arrays;
import java.util.Iterator;

/**
 * Rdd中不会保存数据，这里有四个步骤
 * 1、从TEXT中读取数据
 * 2、flatMap进行组合
 * 3、从flatMap进行mapToPair形成KV
 * 4、从flatMap进行groupBy形成KV
 * 我在第2步在方法内部进行了打印，如果进行了flatMapRdd.cache()的持久化操作，那么flatMap只会调用一遍，如果没有进行持久化操作，那么就会执行两遍。
 * 缓存是第一遍读取之后才进行缓存的
 *  flatMapRdd.persist(StorageLevel.MEMORY_ONLY())== flatMapRdd.cache()
 *  这里传的参数指的是持久化级别
 *  MEMORY_ONLY=只在内存中，如果内存不够会丢弃其他数据，因此此处建议MEMORY_AND_DISK
 *
 */
public class Spark02_Persist {
    public static void main(String[] args) {

        // 配置SparkConf指向你的Spark master URL
        SparkConf conf = new SparkConf()
                .setAppName("Spark02_Persist") // 应用名称
                .setMaster("local[*]"); // 替换成你的master地址
        JavaSparkContext sc = new JavaSparkContext(conf);

        // 创建JavaSparkContext，它是与集群交互的主要入口点
        try {
            JavaRDD<String> rdd = sc.textFile("data/word.txt");


            JavaRDD<String> flatMapRdd = rdd.flatMap(new FlatMapFunction<String, String>() {
                @Override
                public Iterator<String> call(String s) throws Exception {
                    System.out.println("读取……………………………………………………………………………………………………………………………………………………………………");
                    Iterator<String> iterator = Arrays.asList(s.split(" ")).iterator();
                    return iterator;
                }
            });

            flatMapRdd.persist(StorageLevel.MEMORY_AND_DISK());

            JavaPairRDD<String, Integer> stringIntegerJavaPairRDD = flatMapRdd.mapToPair(new PairFunction<String, String, Integer>() {
                @Override
                public Tuple2<String, Integer> call(String s) throws Exception {
                    return new Tuple2<>(s, 1);
                }
            });


            stringIntegerJavaPairRDD.collect().forEach(System.out::println);

            JavaPairRDD<Object, Iterable<String>> objectIterableJavaPairRDD = flatMapRdd.groupBy(new Function<String, Object>() {
                @Override
                public Object call(String v1) throws Exception {
                    return v1;
                }
            });


            objectIterableJavaPairRDD.collect().forEach(System.out::println);
        } finally {
            sc.close();
        }
    }
}
